package com.grailslm.json

import groovy.json.JsonSlurper

/**
 * Json差异对比
 * @author 吕常龙
 */
class JsonDiff {

    Object sourceObject // new JsonSlurper().parseText(strJson)
    Object targetObject // new JsonSlurper().parseText(strJson)

    LinkedHashMap source //来源，开始状态
    LinkedHashMap target //目标，结束状态
    Map intersection //交集，没有改变的量

    JsonDiff(String strSource, String strTarget) {
        def sourceHelper = new JsonString2JsonPathMap(strSource)
        this.sourceObject = sourceHelper.dsObject
        this.source = sourceHelper.exec()

        def targetHelper = new JsonString2JsonPathMap(strTarget)
        this.targetObject = targetHelper.dsObject
        this.target = targetHelper.exec()

        this.intersection = this.source.intersect(this.target)
    }

    /**
     * 已删除的元素
     */
    private def deleted() {
        def combine = source + target //覆盖替换
        return combine - target //排除掉变化的和新增的元素
    }

    /**
     * 被添加的元素
     */
    private def added() {
        def combine = target + source //覆盖替换
        return combine - source //排除掉变化的和新增的元素
    }

    /**
     * 被修改的元素
     */
    private def modified() {
        return target - intersection - this.added() //排除掉未发生变化的和新增的元素
    }

    ArrayList<LinkedHashMap> deletedWrapper() {
        return this.wrapper(this.deleted())
    }
    ArrayList<LinkedHashMap> addedWrapper() {
        return this.wrapper(this.added())
    }
    ArrayList<LinkedHashMap> modifiedWrapper() {
        return this.wrapper(this.modified())
    }

    private ArrayList<LinkedHashMap> wrapper(LinkedHashMap map) {
        ArrayList arrayList = new ArrayList()
        map.each {key, value->
            LinkedHashMap linkedHashMap = new LinkedHashMap()
            linkedHashMap.put("path", key)
            try {
                linkedHashMap.put("src", Eval.x(sourceObject, key))
            } catch(Exception e) {
                linkedHashMap.put("src", null)
            }
            linkedHashMap.put("tar", value)
            arrayList.add(linkedHashMap)

        }
        return arrayList
    }

    static main(args) {
        def util = new JsonDiff(this.getResourceAsStream("source.json").text, this.getResourceAsStream("target.json").text)

        println "被添加的：" + util.added()
        println "被删除的：" + util.deleted()
        println "被修改的：" + util.modified()

        println "-------------------------------------"

        println "被添加的：" + util.addedWrapper()
        println "被删除的：" + util.deletedWrapper()
        println "被修改的：" + util.modifiedWrapper()

        println "-------------------------------------"

        println ([1, 2, 3] + [1, 4]) //List运算-追加
        println (["x":[1, 2, 3]] + ["x":[1, 4]]) //Map运算-覆盖
    }

}
